import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression

"""构造数据"""
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)
x_b = np.c_[np.ones([100, 1]), x]  # 加上一列1，横向用r_

"""做个图看一眼"""
plt.scatter(x, y, label="Train data")
plt.xlabel("x")
plt.ylabel("y")
plt.title("train")
plt.legend()  # 显示label
plt.show()

"""算法实例化"""
lin_reg = LinearRegression()

"""进行训练"""
lin_reg.fit(x, y)
print("权重参数：", lin_reg.coef_)  # 权重参数
print("偏置参数：", lin_reg.intercept_)  # 偏置参数

"""梯度下降"""
eta = 0.1  # 学习率
n_iterations = 1000  # 迭代次数
m = 100  # 样本个数
theta = np.random.randn(2, 1)  # 参数的随机初始化

cost_history = []  # 损失
"""迭代"""
for i in range(n_iterations):
    # 批量梯度下降公式
    grandients = 2 / m * x_b.T.dot(x_b.dot(theta) - y)
    theta = theta - eta * grandients  # 更新参数矩阵
    delta = np.dot(x_b, theta) - y
    cost_history.append((0.5 * np.dot(delta.T, delta) / m)[0][0])
print("参数矩阵：", theta)

"""画出来损失函数的趋势"""
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.plot(range(len(cost_history)), cost_history)
plt.xlabel("迭代次数")
plt.ylabel("损失")
plt.title("梯度下降")
plt.show()


"""测试参数"""
x_new = np.array([[0], [2]])  # 构造新数据
x_new_b = np.c_[np.ones([2, 1]), x_new]  # 加一列偏置项
y_predict = x_new_b.dot(theta)
print("预测值：", y_predict)

"""画出来回归方程"""
plt.scatter(x, y, label="Train data")
plt.scatter(x_new, y_predict, label="Test data")
plt.plot(x_new, y_predict, 'r', label="回归方程")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Happy")
plt.legend()
plt.show()


